package com.aryankh.core;

import com.aryankh.configuration.CustomObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;

import javax.annotation.Resource;
import java.util.Set;

/**
 * @version 1.0
 * @Author AryanKH
 * @Date 2022/5/28 9:35
 * @Default
 */
@Component
@Slf4j
public class RedisTemplate {
    @Resource
    private JedisPool jedisPool;

    @Resource
    private CustomObjectMapper objectMapper;

    //保存string数据类型的数据
    public String set(String key, String value, Long expireTime) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = "";
        try {
            String setex = jedis.setex(key, expireTime, value);
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return returnValue;
    }


    //保存string数据类型的数据
    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = null;
        try {
            String s = jedis.get(key);
            return returnValue = s;
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
    }

    //将对象以序列化的方式存在redis里 JSON
    //保存string数据类型的数据
    public String setObject(String key, Object value, Long expireTime) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = "";
        try {
            //首先先序列化成json
            String jsonValue = objectMapper.writeValueAsString(value);

            if (expireTime <= 0) {
                returnValue = jedis.set(key, jsonValue);
            } else {
                returnValue = jedis.setex(key, expireTime, jsonValue);
            }
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return returnValue;
    }

    public <T> T getObject(String key, TypeReference<T> typeReference) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = "";
        T object = null;
        try {
            returnValue = jedis.get(key);
            object = objectMapper.readValue(returnValue, typeReference);
            return object;
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
    }

    //保存string数据类型的数据
    public long remove(String... key) {
        Jedis jedis = jedisPool.getResource();
        long del = 0L;
        try {
            del = jedis.del(key);
            return del;
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
    }

    //增加key的时间
    public Long expire(String key,Long expireTime) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = "";
        long exp=-1L;
        try {
            exp = jedis.expire(key, expireTime);
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return exp;
    }


    //查询特定的key
    public Set<String> keys(String pattern) {
        Jedis jedis = jedisPool.getResource();
        String returnValue = "";
        Set<String> keys=null;
        try {
            keys  = jedis.keys(pattern);
        } catch (JedisException e) {
            log.error("redis execution error", e);
            jedisPool.returnBrokenResource(jedis);
            throw new JedisException(e);
        } finally {
            jedisPool.returnResource(jedis);
        }
        return keys;
    }

}
